package com.jwsoft.manager.core.integration.impl;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.IdcardUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bifang.engine.assistant.core.annotation.ApiService;
import com.bifang.engine.assistant.core.annotation.OpApi;
import com.bifang.engine.assistant.core.annotation.SaveOplog;
import com.bifang.engine.assistant.core.enums.AuTypeEnum;
import com.bifang.engine.assistant.core.enums.FuncTypeEnum;
import com.bifang.engine.assistant.core.utils.SessionUtil;
import com.bifang.engine.data.core.util.PagerUtil;
import com.bifang.module.base.core.helper.DictHelper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jwsoft.manager.common.enums.AreaEnum;
import com.jwsoft.manager.common.enums.CardTypeEnum;
import com.jwsoft.manager.common.enums.EduAreaCodeEnum;
import com.jwsoft.manager.common.enums.EnrollStatusFormalEnum;
import com.jwsoft.manager.common.vo.eduSchool.EduSchoolVO;
import com.jwsoft.manager.common.vo.eduStudentEnroll.EduStudentEnrollQueryVO;
import com.jwsoft.manager.common.vo.eduStudentEnroll.EduStudentEnrollVO;
import com.jwsoft.manager.core.dao.model.EduStudentEnroll;
import com.jwsoft.manager.core.dao.service.EduSchoolService;
import com.jwsoft.manager.core.dao.service.EduStudentEnrollService;
import com.jwsoft.manager.core.util.EduHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import cn.hutool.core.convert.Convert;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import com.bifang.engine.assistant.core.exception.AppException;
import org.springframework.util.ObjectUtils;
import org.springframework.transaction.annotation.Transactional;
import com.bifang.engine.assistant.core.enums.BoolEnum;
import com.jwsoft.manager.common.vo.eduClassStudent.EduClassStudentVO;
import com.jwsoft.manager.common.vo.eduClassStudent.EduClassStudentKeyVO;
import com.jwsoft.manager.common.vo.eduClassStudent.EduClassStudentQueryVO;
import com.jwsoft.manager.core.integration.EduClassStudentIntegration;
import com.jwsoft.manager.core.dao.service.EduClassStudentService;
import com.jwsoft.manager.core.dao.model.EduClassStudent;

/**
 * 分班学生名单管理业务实现类
 *
 * @author chenzh
 * @since 2023-08-21
 */
@ApiService(funcCode = "eduClassStudent", title = "分班学生名单管理")
public class EduClassStudentIntegrationImpl implements EduClassStudentIntegration {

    @Autowired
    public EduClassStudentService eduClassStudentService;

    @Autowired
    private EduHelper eduHelper;

    @Autowired
    private EduStudentEnrollService eduStudentEnrollService;

    @Autowired
    private EduSchoolService eduSchoolService;

    //查询的条数
    private final Integer QUERY_MAX_SIZE = 1000;

    private final String ENROLL_STATUS = "2";

    @Autowired
    private DictHelper dictHelper;

    @Override
    @OpApi(funcCode = "eduClassStudent0001", title = "分班学生名单管理分页查询", funcType = FuncTypeEnum.query)
    public PageInfo<EduClassStudentVO> getList(EduClassStudentQueryVO vo) {
        // 开启分页
        if (vo.getPageNum() == null || vo.getPageSize() == null) {
            //如果不传入分页参数，默认最大取1000条
            vo.setPageNum(1);
            vo.setPageSize(1000);
        }
        if (ObjectUtils.isEmpty(vo.getYear())){
            vo.setYear(eduHelper.thisYear());
        }
        if (!ObjectUtils.isEmpty(vo.getSearchText())) {
            vo.setFullName(vo.getSearchText());
        }
        QueryWrapper<EduClassStudent> queryWrapper = new QueryWrapper<>();
        String orgId = SessionUtil.getOrgId();
        EduSchoolVO school = eduSchoolService.getDetail(orgId);
        if (!ObjectUtils.isEmpty(school)){
            queryWrapper.lambda().eq(EduClassStudent::getSchoolId,orgId);
        }else{
            queryWrapper.lambda().eq(!ObjectUtils.isEmpty(vo.getSchoolId()),EduClassStudent::getSchoolId,vo.getSchoolId());
        }
        queryWrapper.lambda()
                .eq(EduClassStudent::getYear,vo.getYear())
                .like(!ObjectUtils.isEmpty(vo.getFullName()),EduClassStudent::getFullName,vo.getFullName())
                .eq(!ObjectUtils.isEmpty(vo.getIdcard()),EduClassStudent::getIdcard,vo.getIdcard())
                .eq(!ObjectUtils.isEmpty(vo.getFollowingFlag()),EduClassStudent::getFollowingFlag,vo.getFollowingFlag())
                .eq(!ObjectUtils.isEmpty(vo.getSchoolCategory()),EduClassStudent::getSchoolCategory,vo.getSchoolCategory())
                .eq(!ObjectUtils.isEmpty(vo.getSchoolNature()),EduClassStudent::getSchoolNature,vo.getSchoolNature())
                .eq(!ObjectUtils.isEmpty(vo.getConfigTypeName()),EduClassStudent::getConfigTypeName,vo.getConfigTypeName())
                .like(!ObjectUtils.isEmpty(vo.getFatherName()),EduClassStudent::getFatherName,vo.getFatherName())
                .eq(!ObjectUtils.isEmpty(vo.getFatherIdcard()),EduClassStudent::getFatherIdcard,vo.getFatherIdcard())
                .like(!ObjectUtils.isEmpty(vo.getMotherName()),EduClassStudent::getMotherName,vo.getMotherName())
                .eq(!ObjectUtils.isEmpty(vo.getMotherIdcard()),EduClassStudent::getMotherIdcard,vo.getMotherIdcard())
                .eq(!ObjectUtils.isEmpty(vo.getFatherCellphone()),EduClassStudent::getFatherCellphone,vo.getFatherCellphone())
                .eq(!ObjectUtils.isEmpty(vo.getMotherCellphone()),EduClassStudent::getMotherCellphone,vo.getMotherCellphone())
                .eq(!ObjectUtils.isEmpty(vo.getStudentId()),EduClassStudent::getStudentId,vo.getStudentId())
                .orderByDesc(EduClassStudent::getUpdateTime,EduClassStudent::getFullName);
        ;
        PageHelper.startPage(vo.getPageNum(), vo.getPageSize());
        List<EduClassStudent> list = eduClassStudentService.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            // 判断是否为空，为空则返回空参数
            return PagerUtil.createEmptyPagerInfo(vo.getPageNum(), vo.getPageSize());
        }
        // 不为空则获取分页结果
        PageInfo<EduClassStudent> pageInfo = new PageInfo<>(list);
        // 返回参数需要通过common层的vo实体类，用该方法可以批量转换
        List<EduClassStudentVO> resultList = Convert.toList(EduClassStudentVO.class, pageInfo.getList());
        // 转义数据字典值
         dictHelper.valueToName(resultList, Arrays.asList(EduAreaCodeEnum.values()));
        return PagerUtil.parsePagerVo(resultList, pageInfo);
    }

    @Override
    @OpApi(funcCode = "eduClassStudent0002", title = "分班学生名单管理根据主键查询详情", funcType = FuncTypeEnum.query)
    public EduClassStudentVO getById(EduClassStudentKeyVO vo) {
        EduClassStudent entity = eduClassStudentService.getById(vo.getStudentId());
        if (ObjectUtils.isEmpty(entity)) {
            throw new AppException("查询不到详细信息!");
        }
        EduClassStudentVO result = Convert.convert(EduClassStudentVO.class, entity);
        return result;
    }

    /**
     * 保存前统一校验
     */
    @Override
    @OpApi(funcCode = "eduClassStudent0003", title = "分班学生名单管理保存前校验", funcType = FuncTypeEnum.other, checkPrivilege = BoolEnum.FALSE)
    public void checkSave(EduClassStudentVO vo) {
        //基本数据校验
        if (ObjectUtils.isEmpty(vo.getYear())){
            vo.setYear(eduHelper.thisYear());
        }
        if (ObjectUtils.isEmpty(vo.getAddress())){
            throw new AppException("现居住地址不能为空");
        }
        if (ObjectUtils.isEmpty(vo.getHouseholdAddress())){
            throw new AppException("户籍地址不能为空");
        }
        if (ObjectUtils.isEmpty(vo.getAreaCode())){
            vo.setAreaCode(vo.getAreaCode());
        }
        if (ObjectUtils.isEmpty(vo.getIdcard())){
            throw new AppException("学生身份证不能未空");
        }
        if (ObjectUtils.isEmpty(vo.getCardType())){
            throw new AppException("学生身份证类型不能未空");
        }
        if (ObjectUtils.isEmpty(vo.getFullName())){
            throw new AppException("学生姓名不能未空");
        }
        boolean xsFlag = IdcardUtil.isValidCard(vo.getIdcard());
        if (vo.getCardType().equals(CardTypeEnum.idcard.getType()) && !xsFlag) {
            throw new AppException("学生身份证有误！");
        } else {
            if (xsFlag && !CardTypeEnum.idcard.getType().equals(vo.getCardType())) {
                throw new AppException("学生证件类型，请选择身份证！");
            }
            vo.setIdcard(vo.getIdcard().trim().toUpperCase());
        }
        if (StringUtils.isBlank(vo.getMotherCardType())) {
            vo.setMotherCardType(CardTypeEnum.idcard.getType());
        }
        if (StringUtils.isBlank(vo.getFatherCardType())) {
            vo.setFatherCardType(CardTypeEnum.idcard.getType());
        }

        if(StringUtils.isBlank(vo.getAreaCode())){
            vo.setAreaCode(SessionUtil.getSessionInfo().getAreaCode());
        }
        boolean flag = true;
        if (!ObjectUtils.isEmpty(vo.getMotherIdcard())) {
            boolean motherFlag = IdcardUtil.isValidCard(vo.getMotherIdcard());
            if (CardTypeEnum.idcard.getType().equals(vo.getMotherCardType()) && !motherFlag) {
                throw new AppException("母亲身份证有误！");
            } else {
                if (motherFlag && !CardTypeEnum.idcard.getType().equals(vo.getMotherCardType())) {
                    throw new AppException("母亲证件类型，请选择身份证！");
                }
                vo.setMotherIdcard(vo.getMotherIdcard().trim().toUpperCase());
            }
            if (ObjectUtils.isEmpty(vo.getMotherName())) {
                throw new AppException("母亲姓名不能为空！");
            } else {
                vo.setMotherName(
                        Validator.isChinese(vo.getMotherName())
                                ? vo.getMotherName().replace(" ", "").trim()
                                : vo.getMotherName().trim());
            }
            flag = false;
        }

        if (!ObjectUtils.isEmpty(vo.getFatherIdcard())) {
            boolean fatherFlag = IdcardUtil.isValidCard(vo.getFatherIdcard());
            if (CardTypeEnum.idcard.getType().equals(vo.getFatherCardType()) && !fatherFlag) {
                throw new AppException("父亲(监护人)身份证有误！");
            } else {
                if (fatherFlag && !CardTypeEnum.idcard.getType().equals(vo.getFatherCardType())) {
                    throw new AppException("父亲(监护人)证件类型，请选择身份证！");
                }
                vo.setFatherIdcard(vo.getFatherIdcard().trim().toUpperCase());
            }
            if (ObjectUtils.isEmpty(vo.getFatherName())) {
                throw new AppException("父亲(监护人)姓名不能为空！");
            } else {
                vo.setFatherName(
                        Validator.isChinese(vo.getFatherName())
                                ? vo.getFatherName().replace(" ", "").trim()
                                : vo.getFatherName().trim());
            }
            flag = false;
        }
        if (ObjectUtils.isEmpty(vo.getFullName())) {
            throw new AppException("学生姓名不能为空！");
        } else {
            vo.setFullName(
                    Validator.isChinese(vo.getFullName())
                            ? vo.getFullName().replace(" ", "").trim()
                            : vo.getFullName().trim());
        }
        if (flag) {
            throw new AppException("父亲（监护人）或母亲一方必填");
        }

        if (xsFlag) {
            if (StringUtils.isBlank(vo.getBirthYmd())) {
                vo.setBirthYmd(IdcardUtil.getBirth(vo.getIdcard()));
            }
            if (StringUtils.isBlank(vo.getSex())) {
                int gender = IdcardUtil.getGenderByIdCard(vo.getIdcard());
                if (gender == 1) {
                    // 男
                    vo.setSex("1");
                } else {
                    // 女
                    vo.setSex("2");
                }
            }
        }
        if (ObjectUtils.isEmpty(vo.getSchoolId())){
            throw new AppException("学校信息不能为空");
        }
        if (ObjectUtils.isEmpty(vo.getFollowingFlag())){
            throw new AppException("是否随迁不能为空");
        }

        //主键为空为新增校验

        //主键不为空为修改校验
    }

    @Override
    @OpApi(funcCode = "eduClassStudent0004", title = "分班学生名单管理新增", funcType = FuncTypeEnum.insert)
    @SaveOplog(
            operationType = "eduClassStudent0004",
            operationName = "分班学生名单管理新增",
            dataType = "studentId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public EduClassStudentVO add(EduClassStudentVO vo) {
        //保存前校验
        checkSave(vo);
        EduSchoolVO school = eduSchoolService.getDetail(vo.getSchoolId());
        if (ObjectUtils.isEmpty(school)){
            throw new AppException("数据有误，请刷新后重试");
        }
        //设置学校信息
        vo.setSchoolName(school.getShortName());
        vo.setSchoolNature(school.getSchoolNature());
        vo.setSchoolCategory(school.getSchoolCategory());
        //保存数据
        EduClassStudent entity = Convert.convert(EduClassStudent.class, vo);
        eduClassStudentService.save(entity);
        //将主键设置回vo使操作日志可以取到
        vo.setStudentId(entity.getStudentId());
        return vo;
    }

    @Override
    @OpApi(funcCode = "eduClassStudent0005", title = "分班学生名单管理修改", funcType = FuncTypeEnum.update)
    @SaveOplog(
            operationType = "eduClassStudent0005",
            operationName = "分班学生名单管理修改",
            dataType = "studentId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public EduClassStudentVO edit(EduClassStudentVO vo) {
        if (ObjectUtils.isEmpty(vo.getStudentId())) {
            throw new AppException("传入需要修改的主键不能为空!");
        }
        EduClassStudent oldEntity = eduClassStudentService.getById(vo.getStudentId());
        if (ObjectUtils.isEmpty(oldEntity)) {
            throw new AppException("查询不到需要修改的信息!");
        }
        if (!vo.getSchoolId().equals(oldEntity.getSchoolId())){
            EduSchoolVO detail = eduSchoolService.getDetail(vo.getSchoolId());
            vo.setSchoolCategory(detail.getSchoolCategory());
            vo.setSchoolName(detail.getShortName());
            vo.setSchoolNature(detail.getSchoolNature());
        }
        //保存前校验
        checkSave(vo);
        //保存数据
        EduClassStudent entity = Convert.convert(EduClassStudent.class, vo);
        eduClassStudentService.updateById(entity);
        return vo;
    }

    @Override
    @OpApi(funcCode = "eduClassStudent0006", title = "分班学生名单管理根据主键删除", funcType = FuncTypeEnum.delete)
    @SaveOplog(
            operationType = "eduClassStudent0006",
            operationName = "分班学生名单管理删除",
            dataType = "studentId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public void del(EduClassStudentKeyVO vo) {
        if (ObjectUtils.isEmpty(vo.getStudentId())) {
            throw new AppException("传入需要删除的数据主键不能为空!");
        }
        EduClassStudent entity = eduClassStudentService.getById(vo.getStudentId());
        if (ObjectUtils.isEmpty(entity)) {
            throw new AppException("未找到需要删除的信息!");
        }
        eduClassStudentService.removeById(vo.getStudentId());
    }

    @Override
    @OpApi(funcCode = "eduClassStudent0007", title = "分班基础信息初始化", funcType = FuncTypeEnum.insert)
    @SaveOplog(
            operationType = "eduClassStudent0007",
            operationName = "分班基础信息初始化",
            dataType = "studentId",
            auType = AuTypeEnum.OTHER)
    public void classStudentInitialize(EduClassStudentQueryVO vo) {
        if (ObjectUtils.isEmpty(vo.getSchoolId())){
            throw new AppException("学校id不能为空");
        }
        Integer year = eduHelper.thisYear();
        //查询数据进行处理
       boolean flag = true;
        while (flag){
            List<EduStudentEnroll> eduStudentEnrollList
                    =eduStudentEnrollService.queryEnrollStudentNotInClassStudent(year,vo.getSchoolId(),QUERY_MAX_SIZE,ENROLL_STATUS);
            if (ObjectUtils.isEmpty(eduStudentEnrollList)){
                flag = false;
            }
            List<EduClassStudent> studentList = eduStudentEnrollList.stream().map(item -> {
                EduClassStudent eduClassStudent = new EduClassStudent();
                setEnrollData(item,eduClassStudent);
                //设置数据
                return eduClassStudent;
            }).collect(Collectors.toList());
            eduClassStudentService.saveBatch(studentList);
        }

    }

    private void setEnrollData(EduStudentEnroll item, EduClassStudent eduClassStudent) {
        BeanUtils.copyProperties(item, eduClassStudent);
        String birthYmd = eduClassStudent.getBirthYmd();
        int birthYear = Integer.parseInt(birthYmd.substring(0, 4));
        int currentYear = eduClassStudent.getYear();
        eduClassStudent.setAge(currentYear - birthYear);
    }


}
